import {supportFunction as S} from "../../utils/supportFunction";
import jQuery from "jquery";
import {ConstVariable} from "../support/ConstVariable";
import {MidwareConfig} from "../midware";

class ICPlayerProvider {

    /**
     * @return {Function}
     */
    static ConstructorAdapter() {
        if (window.icCreatePlayer === undefined) {
            return function (target) {}
        }
        return function (target) {
            //定义ICPlayer的事件处理器
            S.defineProperty(target.prototype, 'onEventReceived', function (name, data) {
                if (!this.webEvents) {
                    return;
                }
                $.each(this.webEvents, (index, value) => {
                    if (value.name === name) {
                        $.each(value.callbacks, (i, v) => {
                            //将数据交给响应对象进行处理
                            v.call(this, data, name);
                        });
                        return false;
                    }
                });
            });
            S.defineProperty(target.prototype, 'webEvents', [], {writable: true});
            S.defineProperty(target.prototype, 'nativeListener', {}, {writable: true});
            S.defineProperty(target.prototype, 'nativeBridge', window["Bridge"] ? window["Bridge"] : defaultNativeBridge);
        }
    }

    /**
     * @return {Function}
     */
    static MethodAdapter() {
        if (window.icCreatePlayer === undefined) {
            return function (target, key, descriptor) { return descriptor; }
        }
        return function (target, key, descriptor) {
            let method = descriptor.value;
            //对方法进行适配
            switch (key) {
                case "requireComponent":
                    descriptor.value = function (...args) {
                        const adaptedOptions = requireAdapter(args);
                        return method.call(this, adaptedOptions);
                    };
                    break;
                case "addEventListener":
                    descriptor.value = function (...args) {
                        const name = arguments[0], type = arguments[1], callback = arguments[2];
                        if (callback === null || typeof callback !== 'function') {
                            throw Error('callback is null or not a function');
                        }
                        if(type === ConstVariable.PresenterEventType.IC_PLAYER_EVENT) {
                            let hasExists = false;
                            for (let i = 0; i < this.webEvents.length; i++) {
                                if (this.webEvents[i].name === name) {
                                    this.webEvents[i].callbacks.push(callback);
                                    hasExists = true;
                                    break;
                                }
                            }
                            if (!hasExists) {
                                this.webEvents.push({name: name, callbacks: [callback]});
                                this._playerController.getEventBus().addEventListener(name, this);
                            }
                        } else if(type === ConstVariable.PresenterEventType.NATIVE_EVENT) {
                            var eventKey = this.nativeBridge.registerListener(name, callback, this);
                            this.nativeListener[eventKey] = eventKey;
                        }
                    };
                    break;
                case "removeEventListener":
                    descriptor.value = function () {
                        //移除监听的原生事件
                        if (this.nativeListener) {
                            jQuery.each(this.nativeListener, (name, item) => {
                                this.nativeBridge.unRegisterListener(name, item);
                            });
                            this.nativeListener = null;
                        }
                        if (this.webEvents) {
                            //移除监听的Web层事件
                            while (this.webEvents.length > 0) {
                                this.webEvents.pop();
                            }
                            this.webEvents = null;
                        }
                    };
                    break;
                case "dispatchEvent":
                    descriptor.value = function (...args) {
                        const name = args[0], type = args[1], data = args[2] || {};
                        if (type === ConstVariable.PresenterEventType.IC_PLAYER_EVENT) {
                            this.PlayerController.getEventBus().sendEvent(name, data);
                            return true;
                        } else if (type === ConstVariable.PresenterEventType.NATIVE_EVENT ||
                            type === ConstVariable.PresenterEventType.PPT_NATIVE_EVENT) {
                            let bridgeName = "";
                            if(MidwareConfig.NativeBridgeClass !== undefined) {
                                bridgeName = MidwareConfig.NativeBridgeClass;
                            } else {
                                //如果是作业系统
                                if (this.embedApplication("exercise")) {
                                    bridgeName = ConstVariable.PresenterBridge.HOMEWORK;
                                } else {
                                    bridgeName = ConstVariable.PresenterBridge.SMART_CLASS;
                                }
                            }
                            if (type === ConstVariable.PresenterEventType.NATIVE_EVENT) {
                                //APP原生事件类型
                                return this.nativeBridge.callNative(bridgeName, name, data);
                            } else if (type === ConstVariable.PresenterEventType.PPT_NATIVE_EVENT) {
                                //应用于101PPT的原生事件类型,需要做二次包装
                                return this.nativeBridge.callNative(bridgeName, 'sendEvent', {
                                    eventName: name,
                                    eventData: data
                                })
                            }
                        }
                    };
                    break;
                case "_init":
                    descriptor.value = function () {
                        if(window.player) {
                            const currentRuntime = window.player.getPlayerServices().getRuntime();
                            this._environment.isApp = currentRuntime == window.icCreatePlayer.RUNTIME.STUDENT_MOBILE ||
                                currentRuntime == window.icCreatePlayer.RUNTIME.TEACHER_MOBILE;
                            this._environment.isWeb = currentRuntime == window.icCreatePlayer.RUNTIME.WEB;
                            this._environment.isPC = currentRuntime == window.icCreatePlayer.RUNTIME.TEACHER_PC;
                            this._environment.isTeacher = currentRuntime == window.icCreatePlayer.RUNTIME.TEACHER_MOBILE;
                            this._environment.isStudent = currentRuntime == window.icCreatePlayer.RUNTIME.STUDENT_MOBILE;
                        }
                        method.call(this);
                    };
                    break;
            }
            descriptor.writable = descriptor.enumerable = descriptor.configurable = false;
            return descriptor;
        }
    }
}

function requireAdapter(...args) {
    const name = args[0][0], props = args[0][1], rendTo = args[0][2], layout = args[0][3];
    let id = name;
    //在Properties中查找是否存在'__Id'的字段
    if ((props !== null || props !== undefined) && props.length > 0) {
        props.forEach(item=> {
            if (item.name === '__Id') {
                id = item.value;
            }
        });
    }
    const adaptedOptions = {
        addonId: name,
        id: id,
        layout: {
            left: 0,
            top: 0,
            width: "100%",
            height: "100%"
        },
        properties: props === null ? [] : props
    };
    if (layout && layout !== null) {
        //合并布局配置
        jQuery.extend(adaptedOptions.layout, layout);
        if (layout.zindex !== undefined) {
            adaptedOptions["z-index"] = layout.zindex;
        }
    }
    if (rendTo !== null) {
        jQuery.extend(adaptedOptions, {renderTo: rendTo});
    }
    return adaptedOptions;
}

let defaultNativeBridge = {
    registerListener: function () {
        console.warn("window bridge is null, this message from default bridge");
        return {};
    },
    unRegisterListener: function () {
        console.warn("window bridge is null, this message from default bridge");
        return {};
    },
    callNative: function () {
        console.warn("window bridge is null, this message from default bridge");
        return {};
    }
};

export {ICPlayerProvider}